/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
"""
Not ready yet...
\brief Component base class for creating Gimbo-components
\author Tapio Taipalus
"""

import sys, time
sys.path.append("../GIMI/wrap/Python/lib/")

import threading, thread
import gimi, gimimessage


#define GIMI_CLIENT_API (20000)
#include "gimi.h"
#include "Component.hpp"

class receiverThread(threading.Thread):
	def __init__(self, parent, callBack, interval):
		threading.Thread.__init__(self)
		self.p = parent
		self.callBack = callBack
		self.interval = interval

	def run(self):
		while self.p.bRunning:
			msg = gimimessage.GIMIMessage()
			receiveResult = self.p.gi.receive(msg, 0)
		#	print "receiveResult: %i"%receiveResult
			if receiveResult == 0:
				name = self.p.gi.findClientName("", msg.senderId)
				if name[0]:
					sender = contact(name[1], self.p.own.ip, self.p.own.port)
				else:
					sender = contact(msg.senderId, self.p.own.ip, self.p.own.port)
				ret = [msg.data, sender]
				self.callBack(ret)
			else:
				time.sleep(self.interval)
		print "%s IPC receiver: exited" % self.p.own.name


class CComponent():
	def __init__(self, GimboID, ReportID, connectedGIM):
		"""Component base class for creating Gimbo-components"""
		print "CComponent initializing...",

#		self.callBack = None
		self.GimboID = GimboID # aka target
		self.ReportID = ReportID
#		self.newMessage = []
#		self.msgMutex = thread.allocate_lock()
#		self.sendMutex = thread.allocate_lock()
		self.receiver = None
		self.gi = connectedGIM
		self.bRunning = False
		self.minor = 0
		self.GimnetAPName = self.gi.getHubAddress()
		self.GimnetAPPort = self.gi.getHubPort()
		print "Starting using targetID %d and reportID %d"%(self.GimboID, self.ReportID)
  
		#set up services
		bufferID= self.gi.reserveBufferIdentifier();
		self.gi.addRedirection(bufferID, gimi.GIMI_PROTOCOL_GIMBOCTRL);
		self.gi.addProvidedService(gimi.GIMI_PROTOCOL_GIMBOCTRL,self.minor);
		self.gi.addAcceptedService(gimi.GIMI_PROTOCOL_GIMBOCTRL);
		self.gi.setQueueMaxSize(gimi.GIMI_PROTOCOL_GIMBOCTRL, self.minor, 1000000);
		self.gi.setQueueMaxSize(gimi.GIMI_PROTOCOL_GIMBOCTRL, self.minor, 1000000, bufferID);
		self.gi.setQueueMaxSize(gimi.GIMI_PROTOCOL_GIMBOCTRL, -1, 1000000);
		self.gi.setQueueMaxSize(gimi.GIMI_PROTOCOL_GIMBOCTRL, -1, 1000000, bufferID);
	
		#report to target that we are online
		binbag.Clear()
		binbag.AddBinary(ETypeReport,(char*)&report,sizeof(TReport));
		ret =  self.gi.send(self.GimboID,binbag.GetBuffer(), binbag.GetBufferSize(), 
			gimi.GIMI_PROTOCOL_GIMBOCTRL, minor)
		if ret == gimi.GIMI_OK
		{
			run=true;
			
			RunThread();
			
			return true;
		}
		return false;
}


	def SetServiceAssignmentCallBack(self, callbackFunc):
		"""setReceiverCallback(callBack, interval) 
		starts receiving thread and calls callBack for every
		new message.
		callBack([msg.data, sender]), call back function
		interval, seconds (float) to wait before polling gimnet receive again  
		"""
		if self.running:
			print "span receiver thread"
			self.receiver = receiverThread(self, callBack, interval)	
			print "start receiver thread"
			self.receiver.start()
		print 'The main program continues to run in foreground.'


	def close(self):
		self.running = False
		self.gi.stop()		
		
	def Start(self, ):
		"""
     * Start
     * Reports to the controlling Gimbo instance and starts the thread that 
     * receives data over gimi and calls event handler callbacks
     * 
     * @return  true if report was succesful and component started, false on 
     *          failure
     */"""
		self.gimi = gimi
		
	
	def OnServiceAssignment(self, ServiceAssignmentList):
		"""
    /** OnServiceAssignment
     * 
     * Called when 1 or more service assignments are received.
     * 
     * @param [in] list List of received service assignments
     */"""
    
	def GetGimi(self):
		return self.gimi
	def handleMessage(self, message):
	def GetGimi(self):
		
		

#declare variables aka defaults
#parse parameters
#Connect to AP
#Create Component
#Set Service Assignment CallBack
#Step into loop